package uva.sc.ql.parser; import java.util.ArrayList; import java.util.List; import org.antlr.v4.runtime.misc.NotNull; import uva.sc.core.INode; import uva.sc.core.types.Boolean; import uva.sc.core.types.Number; import uva.sc.core.types.String; import uva.sc.core.types.Type; import uva.sc.ql.ast.IQLExpressionNode; import uva.sc.ql.atom.BooleanAtom; import uva.sc.ql.atom.ID; import uva.sc.ql.atom.NumberAtom; import uva.sc.ql.atom.StringAtom; import uva.sc.ql.expression.Expression; import uva.sc.ql.expression.binaryExpressions.Addition; import uva.sc.ql.expression.binaryExpressions.And; import uva.sc.ql.expression.binaryExpressions.Division; import uva.sc.ql.expression.binaryExpressions.Equals; import uva.sc.ql.expression.binaryExpressions.GreaterThan; import uva.sc.ql.expression.binaryExpressions.GreaterThanEquals; import uva.sc.ql.expression.binaryExpressions.LesserThan; import uva.sc.ql.expression.binaryExpressions.LesserThanEquals; import uva.sc.ql.expression.binaryExpressions.Modulus; import uva.sc.ql.expression.binaryExpressions.Multiplication; import uva.sc.ql.expression.binaryExpressions.NotEquals; import uva.sc.ql.expression.binaryExpressions.Or; import uva.sc.ql.expression.binaryExpressions.Substraction; import uva.sc.ql.expression.unaryExpressions.Minus; import uva.sc.ql.expression.unaryExpressions.Not; import uva.sc.ql.form.Form; import uva.sc.ql.statements.IfStatement; import uva.sc.ql.statements.Question; import uva.sc.ql.statements.Statement; @SuppressWarnings("rawtypes") public class ASTGeneratorVisitor extends QLGrammarBaseVisitor<INode> { /* ========================== Parsing blocks ============================ */ public Form visitForm(@NotNull QLGrammarParser.FormContext ctx) { List<Statement> statementList = new ArrayList<Statement>(); for (QLGrammarParser.StatContext statementContext : ctx.sts) { statementList.add((Statement) visitStat(statementContext)); } return new Form(new ID(ctx.ID().getText()), statementList); } public Question visitQuestion(@NotNull QLGrammarParser.QuestionContext ctx) { java.lang.String label = ctx.STRING().getText(); ID id = new ID(ctx.ID().getText()); Type type = (Type) (this.visit(ctx.type())); if (ctx.expr() != null) { Expression expression = (Expression) this.visit(ctx.expr()); return new Question(label, id, type, expression); } else { return new Question(label, id, type); } } public IfStatement visitIf_stat(@NotNull QLGrammarParser.If_statContext ctx) { Expression expr = (Expression) this.visit(ctx.expr()); List<Question> questionList = new ArrayList<Question>(); for (QLGrammarParser.QuestionContext questionContext : ctx.qs) { questionList.add((Question) visitQuestion(questionContext)); } return new IfStatement(expr, questionList); } /* ============================== Types ================================= */ public Boolean visitTypeBoolean(QLGrammarParser.TypeBooleanContext ctx) { return new Boolean(); } public Number visitTypeNumber(QLGrammarParser.TypeNumberContext ctx) { return new Number(); } public String visitTypeString(QLGrammarParser.TypeStringContext ctx) { return new String(); } /* ============================ Literals ================================ */ public IQLExpressionNode visitString( @NotNull QLGrammarParser.StringContext ctx) { java.lang.String str = ctx.getText(); str = str.substring(1, str.length() - 1).replace("\"\"", "\""); return new StringAtom(str); } public IQLExpressionNode visitNumber( @NotNull QLGrammarParser.NumberContext ctx) { IQLExpressionNode result = null; result = new NumberAtom(Double.valueOf(ctx.getText())); return result; } public IQLExpressionNode visitBoolean(QLGrammarParser.BooleanContext ctx) { return new BooleanAtom(java.lang.Boolean.valueOf(ctx.getText())); } /* ======================== Expressions ================================= */ public Minus visitUnaryMinus(@NotNull QLGrammarParser.UnaryMinusContext ctx) { return new Minus((Expression) this.visit(ctx.expr())); } public Not visitNot(@NotNull QLGrammarParser.NotContext ctx) { return new Not((Expression) this.visit(ctx.expr())); } public IQLExpressionNode visitMultiplication( @NotNull QLGrammarParser.MultiplicationContext ctx) { IQLExpressionNode result = null; Expression firstOperand = (Expression) this.visit(ctx.expr(0)); Expression secondOperand = (Expression) this.visit(ctx.expr(1)); switch (ctx.op.getType()) { case QLGrammarParser.MULT: result = new Multiplication(firstOperand, secondOperand); break; case QLGrammarParser.DIV: result = new Division(firstOperand, secondOperand); break; case QLGrammarParser.MOD: result = new Modulus(firstOperand, secondOperand); break; } return result; } public IQLExpressionNode visitAdditive( @NotNull QLGrammarParser.AdditiveContext ctx) { Expression result = null; Expression firstOperand = (Expression) this.visit(ctx.expr(0)); Expression secondOperand = (Expression) this.visit(ctx.expr(1)); switch (ctx.op.getType()) { case QLGrammarParser.ADD: result = new Addition(firstOperand, secondOperand); break; case QLGrammarParser.SUB: result = new Substraction(firstOperand, secondOperand); break; } return result; } public IQLExpressionNode visitRelational( @NotNull QLGrammarParser.RelationalContext ctx) { IQLExpressionNode result = null; Expression firstOperand = (Expression) this.visit(ctx.expr(0)); Expression secondOperand = (Expression) this.visit(ctx.expr(1)); switch (ctx.op.getType()) { case QLGrammarParser.LTE: result = new LesserThanEquals(firstOperand, secondOperand); break; case QLGrammarParser.GTE: result = new GreaterThanEquals(firstOperand, secondOperand); break; case QLGrammarParser.LT: result = new LesserThan(firstOperand, secondOperand); break; case QLGrammarParser.GT: result = new GreaterThan(firstOperand, secondOperand); break; } return result; } public IQLExpressionNode visitEquality( @NotNull QLGrammarParser.EqualityContext ctx) { IQLExpressionNode result = null; Expression firstOperand = (Expression) this.visit(ctx.expr(0)); Expression secondOperand = (Expression) this.visit(ctx.expr(1)); switch (ctx.op.getType()) { case QLGrammarParser.EQ: result = new Equals(firstOperand, secondOperand); break; case QLGrammarParser.NEQ: result = new NotEquals(firstOperand, secondOperand); break; } return result; } public And visitAnd(@NotNull QLGrammarParser.AndContext ctx) { Expression firstExpression = (Expression) this.visit(ctx.expr(0)); Expression secondExpression = (Expression) this.visit(ctx.expr(1)); return new And(firstExpression, secondExpression); } public Or visitOr(@NotNull QLGrammarParser.OrContext ctx) { Expression firstExpression = (Expression) this.visit(ctx.expr(0)); Expression secondExpression = (Expression) this.visit(ctx.expr(1)); return new Or(firstExpression, secondExpression); } public INode visitParenthesis( @NotNull QLGrammarParser.ParenthesisContext ctx) { return this.visit(ctx.expr()); } public ID visitId(@NotNull QLGrammarParser.IdContext ctx) { return new ID(ctx.ID().getText()); } }